package com.design.factory;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Auther: zch
 * @Date: 2019/6/29 14:54
 * @Description: 车子工厂。工厂是生产某一类产品（对象）的类
 */
public class CarFactory implements ApplicationContextAware ,InitializingBean {


    /**
     * 工厂模式是客户端不知道要生产什么，但是会给描述（业务标识）,由工厂根据业务标识来返回一个实现类对象。
     * 策略模式是客户端生成好想要的对象 ，交给服务端去执行，服务端用对象的接口或者父类来接收，调用业务方法（多态。）
     *  根据业务请求获取业务车子，用父类（接口）来接收
     *  再用父类的接口引用（多态） 来调用业务方法，这是一套通用的算法骨架，看似是接口在调用实际上的具体的实现类在运作（有点类型模板方法。）
     * @param bizRequest
     * @return
     */

    public Car getCar(BizRequest bizRequest){
        for(Car car:carList){
            //调用钩子方法来判断选择出一个实现类。
            if(car.isAvailable(bizRequest)){
                return car;
            }
        }
        throw new UnsupportedOperationException("unsupported BizRequest: " + bizRequest);

    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }
    private ApplicationContext applicationContext;
    private List<Car> carList=new ArrayList<Car>();

    public void afterPropertiesSet() throws Exception {
       Map<String,Car> beansMap=applicationContext.getBeansOfType(Car.class);
       beansMap.entrySet().stream().forEach(e->{
           carList.add(e.getValue());
       });
    }
}
